﻿//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI;
using Windows.UI.Xaml;
using Expenses.ExpenseService;

namespace Expenses.ViewModels
{
    public class ExpenseReportViewModel : ViewModelBase
    {
        #region Properties

        private int id = 0;
        public int Id
        {
            get
            { return id; }

            set
            {
                if (id == value)
                { return; }

                id = value;
                RaisePropertyChanged("Id");
            }
        }

        private int reportNumber = 0;
        public int ReportNumber
        {
            get
            { return reportNumber; }

            set
            {
                if (reportNumber == value)
                { return; }

                reportNumber = value;
                isDirty = true;
                RaisePropertyChanged("ReportNumber");
            }
        }

        private int employeeId = 0;
        public int EmployeeId
        {
            get
            { return employeeId; }

            set
            {
                if (employeeId == value)
                { return; }

                employeeId = value;
                isDirty = true;
                RaisePropertyChanged("EmployeeId");
            }
        }

        private string employeeName = string.Empty;
        public string EmployeeName
        {
            get
            { return employeeName; }

            set
            {
                if (employeeName == value)
                { return; }

                employeeName = value;
                isDirty = true;
                RaisePropertyChanged("EmployeeName");
            }
        }

        private decimal? amount = 0M;
        public decimal? Amount
        {
            get
            { return amount; }

            set
            {
                if (amount == value)
                { return; }

                amount = value;
                isDirty = true;
                RaisePropertyChanged("Amount");
            }
        }

        private string purpose = string.Empty;
        public string Purpose
        {
            get
            { return purpose; }

            set
            {
                if (purpose == value)
                { return; }

                purpose = value;
                isDirty = true;
                RaisePropertyChanged("Purpose");
            }
        }

        private string approver = string.Empty;
        public string Approver
        {
            get
            { return approver; }

            set
            {
                if (approver == value)
                { return; }

                approver = value;
                isDirty = true;
                RaisePropertyChanged("Approver");
            }
        }

        private int? costCenter = 0;
        public int? CostCenter
        {
            get
            { return costCenter; }

            set
            {
                if (costCenter == value)
                { return; }

                costCenter = value;
                isDirty = true;
                RaisePropertyChanged("CostCenter");
            }
        }

        private string notes = string.Empty;
        public string Notes
        {
            get
            {
                return notes;
            }
            set
            {
                if (notes == value)
                { return; }

                notes = value;
                isDirty = true;
                RaisePropertyChanged("Notes");
            }
        }

        private DateTime? dateSaved = null;
        public DateTime? DateSaved
        {
            get
            {
                return dateSaved;
            }

            set
            {
                if (dateSaved == value)
                { return; }

                dateSaved = value;
                isDirty = true;
                RaisePropertyChanged("DateSaved");
            }
        }

        private DateTime? dateSubmitted = null;
        public DateTime? DateSubmitted
        {
            get
            {
                return dateSubmitted;
            }

            set
            {
                if (dateSubmitted == value)
                { return; }

                dateSubmitted = value;
                isDirty = true;
                RaisePropertyChanged("DateSubmitted");
            }
        }

        private StatusType status = 0;
        public StatusType Status
        {
            get
            {
                return status;
            }

            set
            {
                if (status == value)
                { return; }

                status = value;
                isDirty = true;
                RaisePropertyChanged("Status");
            }
        }

        private DateTime? dateResolved = null;
        public DateTime? DateResolved
        {
            get
            {
                return dateResolved;
            }

            set
            {
                if (dateResolved == value)
                { return; }

                dateResolved = value;
                isDirty = true;
                RaisePropertyChanged("DateResolved");
            }
        }

        private decimal? owedToCreditCard = 0M;
        public decimal? OwedToCreditCard
        {
            get
            {
                return owedToCreditCard;
            }

            set
            {
                if (owedToCreditCard == value)
                { return; }

                owedToCreditCard = value;
                RaisePropertyChanged("OwedToCreditCard");
            }
        }

        private decimal? owedToEmployee = 0M;
        public decimal? OwedToEmployee
        {
            get
            {
                return owedToEmployee;
            }

            set
            {
                if (owedToEmployee == value)
                { return; }

                owedToEmployee = value;
                RaisePropertyChanged("OwedToEmployee");
            }
        }

        private bool containsLateCharges = false;
        public bool ContainsLateCharges
        {
            get
            { return containsLateCharges; }

            set
            {
                if (containsLateCharges == value)
                { return; }

                containsLateCharges = value;
                RaisePropertyChanged("ContainsLateCharges");
            }
        }

        private string backgroundColor;
        public string BackgroundColor
        {
            get
            {
                return backgroundColor;
            }

            set
            {
                backgroundColor = value;
                RaisePropertyChanged("BackgroundColor");
            }
        }

        private string foregroundColor;
        public string ForegroundColor
        {
            get
            {
                return foregroundColor;
            }

            set
            {
                foregroundColor = value;
                RaisePropertyChanged("ForegroundColor");
            }
        }

        private bool isDirty = false;
        public bool IsDirty
        {
            get
            {
                return isDirty;
            }

            set
            {
                isDirty = value;
                RaisePropertyChanged("IsDirty");
            }
        }

        #endregion "Properties"

        public ExpenseReportViewModel()
        {
            employeeId = App.EmployeeId;
            employeeName = App.Employee.Name;
            approver = App.Employee.Manager;
            costCenter = 50992;
            purpose = string.Empty;
        }

        public async Task<int> GetNewExpenseReportNumber()
        {
            var expensesService = new ExpenseServiceClient();
            int reportNumber = await expensesService.GetExpenseReportNumberAsync();
            return reportNumber;
        }

        public async Task<ExpenseReportViewModel> GetExpenseReport(int reportNumber)
        {
            var expensesService = new ExpenseServiceClient();
            ExpenseReport report = await
                expensesService.GetExpenseReportAsync(reportNumber);

            var expenseReportViewModel = new ExpenseReportViewModel()
                          {
                              Amount = report.Amount,
                              Approver = report.Approver,
                              CostCenter = report.CostCenter,
                              DateResolved = report.DateResolved,
                              DateSubmitted = report.DateSubmitted,
                              DateSaved = report.DateSaved,
                              EmployeeId = report.EmployeeId,
                              Notes = report.Notes,
                              OwedToCreditCard = report.OwedToCreditCard,
                              OwedToEmployee = report.OwedToEmployee,
                              Purpose = report.Purpose,
                              ReportNumber = report.ReportNumber,
                              Status = (StatusType)report.Status
                          };
            expenseReportViewModel.EmployeeName =
                await GetEmployeeName(expenseReportViewModel.EmployeeId);
            return expenseReportViewModel;
        }

        public async Task<string> SaveExpenseReport(
            ExpenseReportViewModel expenseReport, List<ExpenseItemViewModel> expenseItems, bool submit)
        {
            // Convert report and items to ExpenseReport and ExpenseItems
            var newReport = new ExpenseReport
            {
                Amount = expenseReport.Amount,
                Approver = expenseReport.Approver,
                CostCenter = expenseReport.CostCenter,
                Notes = expenseReport.Notes,
                Purpose = expenseReport.Purpose,
                ReportNumber = expenseReport.ReportNumber

            };

            var newItems = new List<ExpenseItem>();
            foreach (ExpenseItemViewModel item in expenseItems)
            {
                newItems.Add(new ExpenseItem
                {
                    Id=item.Id,
                    BilledAmount = item.BilledAmount,
                    Category = item.Category,
                    Description = item.Description,
                    EmployeeId = item.EmployeeId,
                    ExpenseDate = item.ExpenseDate,
                    Location = item.Location,
                    Merchant = item.Merchant,
                    Notes = item.Notes,
                    AccountNumber = item.AccountNumber,
                    ReceiptRequired = item.ReceiptRequired,
                    TransactionAmount = item.TransactionAmount,
                    ExpenseType = item.ExpenseType,
                    ChargeId = item.ChargeId
                });
            }

            var expensesService = new ExpenseServiceClient();

            string result = await expensesService.SaveExpenseReportAsync(
                expenseReport.EmployeeId, newReport, newItems, submit);
            return result;
        }

        public async Task<string> DeleteExpenseReport(int reportNumber)
        {
            var expensesService = new ExpenseServiceClient();

            string result = "Unknown result";
            result = await expensesService.DeleteExpenseReportAsync(reportNumber);
            return result;
        }

        public async Task<string> ApproveExpenseReport(int reportNumber)
        {
            var expensesService = new ExpenseServiceClient();

            string result = await expensesService.ApproveExpenseReportAsync(reportNumber);
            return result;
        }

        public async Task<string> RejectExpenseReport(int reportNumber)
        {
            var expensesService = new ExpenseServiceClient();

            string result = await expensesService.RejectExpenseReportAsync(reportNumber);
            return result;
        }

        public async Task<string> GetEmployeeName(int employeeId)
        {
            var expensesService = new ExpenseServiceClient();
            string employeeName = await expensesService.GetEmployeeNameAsync(employeeId);
            return employeeName;
        }

    }

}
